iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Software Development

程式基礎概念討論系列 第 6

[DAY 6] 讓程式開始做事的運算式 (下)

  • 分享至 

  • xImage
  •  

今天讓我們繼續討論剩下的運算子~

位元運算子

位元運算子是一種相當特殊的運算子,它會先把運算元轉換為二進位制的數字組合後再為每一個位元的數字進行類似邏輯運算子的運算行為。以下是基本的位元運算子:

  1. AND 位元運算子 (&)
  2. OR 位元運算子 (|)
  3. XOR 位元運算子 (^)
  4. NOT 位元運算子 (~)

等等,這不是跟邏輯運算子一樣嗎?沒錯,基本的位元運算子的種類跟計算方式都跟邏輯運算子非常相似,而不一樣的是位元運算子是針對數字類而不是布林值的資料型態而進行的。接下來就讓我們看一些例子來說明吧~

假設現在我們有兩個數字,分別為 10 跟 12,我們要使用以上的位元運算子來進行計算:

1. 10 & 12
首先,10 跟 12 被分別轉換為二進位制的 1010 跟 1100,然後,位元運算子會單獨的為每一個位元進行計算:

1010 & 1100
========================================================================
位元 1:1 & 1 -> 相等於 True & True 的邏輯運算,因此結果為 1 (True)
位元 2:0 & 1 -> 相等於 False & True 的邏輯運算,因此結果為 0 (False)
位元 3:1 & 0 -> 相等於 True & False 的邏輯運算,因此結果為 0 (False)
位元 4:0 & 0 -> 相等於 False & False 的邏輯運算,因此結果為 0 (False)
========================================================================
因此結果為 1000

當程式得到結果為二進位制的 1000 後,它會重新把結果轉換為我們原來的進位制,在這個例子中便是把二進位制的 1000 轉換為十進位制的 8,因此我們得到 10 & 12 = 8 的結果。

2. 10 | 12
跟上面的例子一樣,10 跟 12 被分別轉換為二進位制的 1010 跟 1100,然後,位元運算子會單獨的為每一個位元進行計算:

1010 | 1100
========================================================================
位元 1:1 | 1 -> 相等於 True | True 的邏輯運算,因此結果為 1 (True)
位元 2:0 | 1 -> 相等於 False | True 的邏輯運算,因此結果為 1 (True)
位元 3:1 | 0 -> 相等於 True | False 的邏輯運算,因此結果為 1 (True)
位元 4:0 | 0 -> 相等於 False | False 的邏輯運算,因此結果為 0 (False)
========================================================================
因此結果為 1110

當程式得到結果為二進位制的 1110 後,它會重新把結果轉換為我們原來的進位制,在這個例子中便是把二進位制的 1110 轉換為十進位制的 14,因此我們得到 10 | 12 = 14 的結果。

3. 10 ^ 12
跟上面的例子一樣,10 跟 12 被分別轉換為二進位制的 1010 跟 1100,然後,位元運算子會單獨的為每一個位元進行計算:

1010 ^ 1100
========================================================================
位元 1:1 ^ 1 -> 相等於 True ^ True 的邏輯運算,因此結果為 0 (False)
位元 2:0 ^ 1 -> 相等於 False ^ True 的邏輯運算,因此結果為 1 (True)
位元 3:1 ^ 0 -> 相等於 True ^ False 的邏輯運算,因此結果為 1 (True)
位元 4:0 ^ 0 -> 相等於 False ^ False 的邏輯運算,因此結果為 0 (False)
========================================================================
因此結果為 0110

當程式得到結果為二進位制的 0110 後,它會重新把結果轉換為我們原來的進位制,在這個例子中便是把二進位制的 0110 轉換為十進位制的 6,因此我們得到 10 ^ 12 = 6 的結果。

4. ~10
由於 NOT 位元運算子跟 NOT 邏輯運算子都是一元運算子,因此這次我們只使用 10 為例子。跟上面的例子一樣,10 被轉換為二進位制的 1010,然後,位元運算子會單獨的為每一個位元進行計算:

~1010
========================================================================
位元 1:~1 -> 相等於 !True 的邏輯運算,因此結果為 0 (False)
位元 2:~0 -> 相等於 !False 的邏輯運算,因此結果為 1 (True)
位元 3:~1 -> 相等於 !True 的邏輯運算,因此結果為 0 (False)
位元 4:~0 -> 相等於 !False 的邏輯運算,因此結果為 1 (True)
========================================================================
因此結果為 0101

當程式得到結果為二進位制的 0101 後,它會重新把結果轉換為我們原來的進位制,在這個例子中便是把二進位制的 0101 轉換為十進位制的 5,因此我們得到 ~10 = 5 的結果。

除了上述提到的位元運算子外,還有兩個較為複雜的位元運算子:左移 (<<) 跟右移 (>>)。有些程式語言會把這兩個運算子稱為移位運算子 (Shift Operators)。移位運算子是把數字轉換為二進位制後把所有的位元向左或右移動並刪除超出位置的位元,然後在空缺的位元補上 0 後把結果轉換為我們原來的進位制,讓我們看一些例子來說明吧~

讓我們繼續以 10 (1010) 為例子,並試圖讓他進行左移 (<<) 跟右移 (>>) 2 位元的動作:

10 << 2

  1. [1010] - 10 被轉換為二進位制的 1010
  2. 10[10__] - 所有數字向左移動了兩個位元,因此左邊的 10 超出了位置並被刪除掉
  3. [1000] - 在右邊空缺的兩個位元補上了 0
    當程式得到結果為二進位制的 1000 後,它會重新把結果轉換為我們原來的進位制,在這個例子中便是把二進位制的 1000 轉換為十進位制的 8,因此我們得到 10 << 2 = 8 的結果。

10 >> 2

  1. [1010] - 10 被轉換為二進位制的 1010
  2. [__10]10 - 所有數字向右移動了兩個位元,因此右邊的 10 超出了位置並被刪除掉
  3. [0010] - 在左邊空缺的兩個位元補上了 0
    當程式得到結果為二進位制的 0010 後,它會重新把結果轉換為我們原來的進位制,在這個例子中便是把二進位制的 0010 轉換為十進位制的 2,因此我們得到 10 >> 2 = 2 的結果。

位元運算子由於它的計算方式比較不直觀,因此較少會被使用在一般的程式中,不過它很常被使用在加密相關的技術跟演算法中。

賦值運算子/指定運算子

賦值運算子是用來把資料儲存到變數的運算子。比較特殊的是它是從右至左運算的。因此,賦值運算子會把運算子右邊的運算元視為需要儲存的資料,而左邊則被視為用來儲存的變數。大多數的程式語言都會以 = 為基本的賦值運算子的表示方式,也就是:

[變數] = [作為儲存資料的運算元]

不過,為了方便工程師們,大多數的程式語言都提供了同時帶有算術運算子或位元運算子的功能的賦值運算子來讓工程師能快速的完成變數儲存的資料跟運算子右邊的運算元的計算行為儲存資料的動作。通常的表示方式是把算術運算子或位元運算子放在基本的賦值運算子的前面,舉例來說,x += a 就是先進行加法計算 x + a 再把結果儲存回變數 x 中。

條件運算子

條件運算子是少數的三元運算子,它是一個被簡化的條件陳述式 (Conditional Statement),用來進行快速的條件判斷。有關條件陳述式的詳細部分跟運作邏輯,我們會在後續的主題中進行更多的討論。而簡單來說,條件運算子是透過判斷第一個運算元的布林值來決定回傳的結果為第二還是第三個的運算元。大多數的程式語言都會以 ?: 為條件運算子的表示方式,也就是:

[布林值資料型態的運算元 1] ? [運算元 1 的值為真 (True) 時回傳的運算元 2] : [運算元 1 的值為假 (False) 時回傳的運算元 3]

其他運算子

除了上述分類的運算子外,根據程式語言的不同,還會有一些特殊的、難以被分類的運算子,如void、in 跟 instanceof 運算子或是括號[()]。由於這些運算子種類繁多,有些更是只有某些程式語言才會有的,因此在這邊便不一一進行介紹,大家有興趣的話可以到使用的程式語言的官方文檔中查詢到詳細的列表跟它們的介紹。

運算子的運算順序

就如同我們在數學進行計算時需要注意像是先乘除後加減之類的規則跟順序,在使用運算子時也有決定優先進行哪個運算子的運算順序規則,而使用相同的運算順序的運算子時則大多是以左到右的順序來進行運算。由於詳細的運算順序規則會有所調整,因此這裡會簡單形容大概的運算順序,大家在使用運算子前可以先確認一下使用的程式語言的運算順序說明。

執行優先度 運算子
1 括號
2 NOT 位元運算子、NOT 邏輯運算子、正負號、一元算術運算子(++/--)
3 乘法(*)、除法(/)、取餘數(%)
4 加法(+)、減法(-)
5 移位運算子(>>/<<)
6 比較大小的運算子(</<=/>/>=)
7 比較是否等於的運算子(==/!=)
8 AND 位元運算子
9 OR 位元運算子
10 XOR 位元運算子
11 AND 邏輯運算子
12 OR 邏輯運算子
13 XOR 邏輯運算子
14 條件運算子
15 賦值運算子

上一篇
[DAY 5] 讓程式開始做事的運算式 (上)
下一篇
[DAY 7] 為不同的變數建立溝通橋樑的型態變換
系列文
程式基礎概念討論30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言